package com.xiaokaceng.openci.web.controller;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

import javax.inject.Inject;

import org.openkoala.koala.auth.ss3adapter.AuthUserUtil;
import org.openkoala.koala.mojo.KoalaProjectCreate;
import org.openkoala.koala.widget.Project;
import org.openkoala.opencis.api.Developer;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.xiaokaceng.openci.application.DeveloperApplication;
import com.xiaokaceng.openci.application.ProjectApplication;
import com.xiaokaceng.openci.domain.CasUserConfiguration;
import com.xiaokaceng.openci.domain.ProjectDetail;
import com.xiaokaceng.openci.domain.ProjectDeveloper;
import com.xiaokaceng.openci.domain.ScmType;
import com.xiaokaceng.openci.dto.ProjectDeveloperDto;
import com.xiaokaceng.openci.dto.ProjectDto;
import com.xiaokaceng.openci.dto.ScmConfig;
import com.xiaokaceng.openci.dto.ToolConfigurationDto;
import com.xiaokaceng.openci.executor.ToolIntegrationExecutor;
import com.xiaokaceng.openci.pojo.ProjectIntegration;
import com.xiaokaceng.openci.web.dto.ResultMsgDto;

@Controller
@RequestMapping("/test")
public class TestController extends BaseController {

	@Inject
	private ProjectApplication projectApplication;

	@Inject
	private ToolIntegrationExecutor toolIntegrationExecutor;

	@Inject
	private DeveloperApplication developerApplication;

	@ResponseBody
	@RequestMapping("/create")
	public void createProject() throws InterruptedException {
		while(true) {
			Thread.sleep(50000);
			ProjectDto projectDto = createProjectDto();
			projectDto.getProjectForCreate().setPath(getProjectSavePath());
			if (!createProjectFile(projectDto.getProjectForCreate())) {
				
			}
			createProjectAndIntegrationTool(projectDto);
		}
	}

	private ProjectDto createProjectDto() {
		String randomStr = randomString();
		ProjectDto projectDto = new ProjectDto(randomStr);
		Project project = new Project();
		project.setAppName(randomStr);
		project.setArtifactId(randomStr);
		project.setGroupId("org.openkoala");
		project.setPackaging("pom");
		project.setVersion("1.0-SNAPSHOT");
		project.setDbProtocol("JPA");
		project.setMvcProtocol("SpringMVC");
		project.setDescription("Auto Created Project");
		projectDto.setProjectForCreate(project);
		generateDefaultModules(projectDto);
		
		projectDto.setProjectForCis(new com.xiaokaceng.openci.domain.Project(randomStr));
		projectDto.setProjectDeveloperDtos(createProjectDeveloperDtos());
		projectDto.setToolConfigurationDtos(createToolConfigurationDtos());
		projectDto.setScmConfig(createScmConfig());
		
		return projectDto;
	}
	
	private ScmConfig createScmConfig() {
		ScmConfig scmConfig = new ScmConfig();
		scmConfig.setScmType(ScmType.GIT);
		scmConfig.setRepositoryUrl("xxx");
		return scmConfig;
	}

	private Set<ToolConfigurationDto> createToolConfigurationDtos() {
		Set<ToolConfigurationDto> toolConfigurationDtos = new HashSet<ToolConfigurationDto>();
		
		toolConfigurationDtos.add(new ToolConfigurationDto(1L));
		toolConfigurationDtos.add(new ToolConfigurationDto(2L));
		toolConfigurationDtos.add(new ToolConfigurationDto(3L));
		toolConfigurationDtos.add(new ToolConfigurationDto(4L));
		toolConfigurationDtos.add(new ToolConfigurationDto(5L));
//		toolConfigurationDtos.add(new ToolConfigurationDto(1L));
//		toolConfigurationDtos.add(new ToolConfigurationDto(3L));
//		toolConfigurationDtos.add(new ToolConfigurationDto(48L));
//		toolConfigurationDtos.add(new ToolConfigurationDto(49L));
//		toolConfigurationDtos.add(new ToolConfigurationDto(50L));
		return toolConfigurationDtos;
	}

	private Set<ProjectDeveloperDto> createProjectDeveloperDtos() {
		Set<ProjectDeveloperDto> projectDeveloperDtos = new HashSet<ProjectDeveloperDto>();
		for (int i = 0; i < 10; i++) {
			String randomId = randomString();
			com.xiaokaceng.openci.domain.Developer developer = new com.xiaokaceng.openci.domain.Developer(randomId, randomId, "12345678", randomId + "@qq.com");
			developerApplication.createDeveloper(developer);
			ProjectDeveloperDto projectDeveloperDto = new ProjectDeveloperDto();
			projectDeveloperDto.setDeveloperId(developer.getId());
			projectDeveloperDtos.add(projectDeveloperDto);
		}
		return projectDeveloperDtos;
	}

	public void generateDefaultModules(ProjectDto projectDto) {
		Project project = projectDto.getProjectForCreate();
		project.initSSJProject();
		project.initModulePrefix(project.getAppName());
	}
	
	private String randomString() {
		String str = "abcdefghijklmnopqrstuvwxyz0123456789";
		Random random = new Random();
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < 10; i++) {
			int num = random.nextInt(36);
			buf.append(str.charAt(num));
		}
		return buf.toString();
	}

	private ResultMsgDto createProjectAndIntegrationTool(ProjectDto projectDto) {
		if (projectApplication.isExistByName(projectDto.getProjectName())) {
			return ResultMsgDto.createFailure("项目名已被创建!");
		}
		inintProject(projectDto);
		if (projectApplication.createProject(projectDto)) {
			com.xiaokaceng.openci.domain.Project project = projectDto.getProjectForCis();
			integrateProjectToTools(project);
			return ResultMsgDto.createSuccess(String.valueOf(project.getId()));
		}
		return ResultMsgDto.createFailure("创建项目失败!");
	}

	private String getProjectSavePath() {
		return System.getProperty("java.io.tmpdir");
	}
	
	private boolean createProjectFile(org.openkoala.koala.widget.Project projectForCreate) {
		KoalaProjectCreate koalaProjectCreate = new KoalaProjectCreate();
		try {
			koalaProjectCreate.createProject(projectForCreate);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	private void inintProject(ProjectDto projectDto) {
		setProjectLead(projectDto);
		setCurrentUserToProjectDeveloper(projectDto);
	}
	
	private void setProjectLead(ProjectDto projectDto) {
		com.xiaokaceng.openci.domain.Project project = projectDto.getProjectForCis();
		project.setLead(AuthUserUtil.getLoginUser().getUsername());
	}

	private void setCurrentUserToProjectDeveloper(ProjectDto projectDto) {
		ProjectDeveloperDto projectDeveloperDto = new ProjectDeveloperDto();
		projectDeveloperDto.setDeveloperId(developerApplication.getByDeveloperId(AuthUserUtil.getLoginUser().getUsername()).getId());
		projectDto.getProjectDeveloperDtos().add(projectDeveloperDto);
		projectDto.configProjectDevelopers();
	}
	
	private void integrateProjectToTools(com.xiaokaceng.openci.domain.Project project) {
		ProjectDetail projectDetail = project.getProjectDetail();
		ProjectIntegration projectIntegration = new ProjectIntegration();
		projectIntegration.setGroupId(projectDetail.getGroupId());
		projectIntegration.setArtifactId(projectDetail.getArtifactId());
		projectIntegration.setProjectName(project.getName());
		projectIntegration.setTools(project.getTools());
		projectIntegration.setProjectSavePath(projectDetail.getProjectSavePath());
		projectIntegration.setDevelopers(transformDevelopers(project.getDevelopers()));
		projectIntegration.setScmConfig(getScmConfig(projectDetail));
		projectIntegration.setProjectLead(project.getLead());
		if (projectDetail.isIntegrationCas()) {
			projectIntegration.setCasUserConfiguration(CasUserConfiguration.getUniqueInstance());
		}
		toolIntegrationExecutor.execute(projectIntegration);
	}

	private ScmConfig getScmConfig(ProjectDetail projectDetail) {
		ScmConfig scmConfig = new ScmConfig();
		scmConfig.setScmType(projectDetail.getScmType());
		scmConfig.setRepositoryUrl(projectDetail.getScmRepositoryUrl());
		return scmConfig;
	}

	private Set<Developer> transformDevelopers(Set<ProjectDeveloper> projectDevelopers) {
		Set<Developer> results = new HashSet<Developer>();
		for (ProjectDeveloper each : projectDevelopers) {
			Developer developer = new Developer();
			developer.setId(each.getDeveloper().getDeveloperId());
			developer.setName(each.getDeveloper().getName());
			developer.setFullName(each.getDeveloper().getDeveloperId());
			developer.setEmail(each.getDeveloper().getEmail());
			developer.setPassword(each.getDeveloper().getPassword());
			results.add(developer);
		}
		return results;
	}
	
}
